home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Zoners Half-Life Tools / template / ReferencePtr.h < prev   
C/C++ Source or Header  |  2001-04-18  |  4KB  |  156 lines

  1. // Copyright (C) 2000  Sean Cavanaugh
  2. // This file is licensed under the terms of the Lesser GNU Public License
  3. // (see LPGL.txt, or http://www.gnu.org/copyleft/lesser.txt)
  4.  
  5. #if !defined(AFX_ReferencePtr_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_)
  6. #define AFX_ReferencePtr_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_
  7.  
  8. #if _MSC_VER > 1000
  9. #pragma once
  10. #endif // _MSC_VER > 1000
  11.  
  12. #ifdef WIN32
  13. #define WIN32_LEAN_AND_MEAN
  14. #include "windows.h"
  15. #endif
  16. #include "assert.h"
  17. #include "limits.h"
  18.  
  19. #ifdef SYSTEM_POSIX
  20. #ifdef HAVE_STDDEF_H
  21. // For NULL
  22. #include <stddef.h>
  23. #endif
  24. #endif
  25.  
  26. #include "ReferenceCounter.h"
  27.  
  28. /*!
  29.   \author  Sean Cavanaugh
  30.   \email   sean@dimensionalrift.com
  31.   \cvsauthor $Author: sean $
  32.   \date    $Date: 2000/09/11 20:28:24 $
  33.   \version $Revision: 1.1 $ 
  34.   \brief   ReferencePtr is a simplified ReferencePtr, primiarily for use with reference counted pointers.
  35.      Its purpose is solely for simplified garbage collection, and not any kind of advanced
  36.      copy on write functionality.  Passing a normal pointer to this class effectively starts
  37.      its reference count at one and should not be manually deleted. (But it may be referenced
  38.      as long as you know the object still exists in some scope somewhere)
  39. */
  40. template<class DATA_T>
  41. class ReferencePtrBlock
  42. {
  43. public:
  44.     DATA_T*            pData;                // User defined data block
  45.     mutable ReferenceCounter ReferenceCount;
  46. };
  47.  
  48.  
  49. template<class DATA_T>
  50. class ReferencePtr  
  51. {
  52. public:
  53.     // Construction
  54.     ReferencePtr();
  55.     ReferencePtr(DATA_T* other);
  56.     ReferencePtr(const ReferencePtr<DATA_T>& other);
  57.     virtual ~ReferencePtr();
  58.  
  59.     // Assignment
  60.     ReferencePtr<DATA_T>& operator=(const ReferencePtr<DATA_T>& other);
  61.     ReferencePtr<DATA_T>& operator=(DATA_T* other);
  62.  
  63.     // Dereferencing
  64.     operator DATA_T*() const {return m_pData->pData;}
  65.     DATA_T* operator->() const {return m_pData->pData;}
  66.  
  67. protected:
  68.     // Internal methods
  69.     void Alloc();                // Allocate the m_pData
  70.     void Release();                // Releases a reference count (possibly freeing memory)
  71.  
  72. protected:
  73.     // Member data
  74.     ReferencePtrBlock<DATA_T>* m_pData;
  75. };
  76.  
  77.  
  78. template<class DATA_T>
  79. ReferencePtr<DATA_T>::ReferencePtr()
  80. {
  81.     Alloc();
  82. }
  83.  
  84. template<class DATA_T>
  85. ReferencePtr<DATA_T>::ReferencePtr(DATA_T* other)
  86. {
  87.     Alloc();
  88.     m_pData->pData = other;
  89.     m_pData->ReferenceCount = 1;
  90. }
  91.  
  92. template<class DATA_T>
  93. ReferencePtr<DATA_T>::ReferencePtr(const ReferencePtr<DATA_T>& other)
  94. {
  95.     m_pData = other.m_pData;
  96.     m_pData->ReferenceCount++;
  97. }
  98.  
  99. template<class DATA_T>
  100. ReferencePtr<DATA_T>::~ReferencePtr()
  101. {
  102.     Release();
  103. }
  104.  
  105. template<class DATA_T>
  106. ReferencePtr<DATA_T>& ReferencePtr<DATA_T>::operator=(const ReferencePtr<DATA_T>& other)
  107. {
  108.     if (m_pData != other.m_pData)
  109.     {
  110.         Release();
  111.         m_pData = other.m_pData;
  112.         m_pData->ReferenceCount++;
  113.     }
  114.     return *this;
  115. }
  116.  
  117. template<class DATA_T>
  118. ReferencePtr<DATA_T>& ReferencePtr<DATA_T>::operator=(DATA_T* other)
  119. {
  120.     if (m_pData->ReferenceCount.dec() <= 0)
  121.     {
  122.         delete m_pData->pData;
  123.         m_pData->pData = other;
  124.         m_pData->ReferenceCount = 1;
  125.     }
  126.     else
  127.     {
  128.         Alloc();
  129.         m_pData->pData = other;
  130.     }
  131.     return *this;
  132. }
  133.  
  134. template<class DATA_T>
  135. void ReferencePtr<DATA_T>::Alloc()
  136. {
  137.     m_pData = new ReferencePtrBlock<DATA_T>;
  138.     m_pData->ReferenceCount = 1;
  139.     m_pData->pData = NULL;
  140. }
  141.  
  142. template<class DATA_T>
  143. void ReferencePtr<DATA_T>::Release()
  144. {
  145.     assert(m_pData != NULL);
  146.     if (m_pData->ReferenceCount.dec() <= 0)
  147.     {
  148.         delete m_pData->pData;
  149.         m_pData->pData = NULL;
  150.         delete m_pData;
  151.         m_pData = NULL;
  152.     }
  153. }
  154.  
  155. #endif // !defined(AFX_ReferencePtr_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_)
  156.